package com.ccys.common.third.payPal.config;

import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @description 描述
 * @date     2024/3/5
 * @author   cloud fly
 * 参考 官方github地址 https://github.com/paypal/PayPal-Java-SDK
 *     * https://github.com/paypal/Checkout-Java-SDK
 */
@RestController
public class PayPalDemoController {

 private Logger log = LoggerFactory.getLogger(getClass());

 @Autowired
 private APIContext apiContext;

 @Value("${pay.paypal.PAYPAL_SUCCESS_PAGE}")
 private String PAYPAL_SUCCESS_PAGE;
 @Value("${pay.paypal.PAYPAL_CANCEL_PAGE}")
 private String PAYPAL_CANCEL_PAGE;

 @Value("${pay.paypal.PAYPAL_SUCCESS_URL}")
 private String PAYPAL_SUCCESS_URL;

 @Value("${pay.paypal.PAYPAL_CANCEL_URL}")
 private String PAYPAL_CANCEL_URL;

 @PostMapping("/payPal")
 public String toPay(){
     //我这里写死了 1
     BigDecimal payAmount = new BigDecimal(1);
     try {
         Payment payment = createPayment(
                 payAmount,
                 "USD",
                 PaypalPaymentMethod.paypal,
                 PaypalPaymentIntent.sale,
                 "购买商品信息~",
                 PAYPAL_CANCEL_URL,
                 PAYPAL_SUCCESS_URL);
         log.info("=========================================");
         log.info(payment.toString());
         log.info("=========================================");
         //保存paypal预支付信息

         //修改订单金额 & 支付的流水号

         log.info("支付金额："+payAmount);
         log.info("订单号："+payment.getId());

         for (Links links : payment.getLinks()) {
             if (links.getRel().equals("approval_url")) {
                 log.info("实际返回正确的地址=" + links.getHref());
                 return links.getHref();
             }
         }
     } catch (PayPalRESTException e) {
         //保存paypal预支付异常信息 .......
         log.error(e.getMessage());
     }
     return "index";
 }


 /**
  * PayPal 支付成功 回调
  * @param response
  * @param paymentId
  * @param payerId
  */
 @GetMapping("/callback/success")
 public void successPay(HttpServletResponse response, @RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId) {
     log.info("================================payPal 回调成功==================================="+paymentId);
     log.info("================================payPal 回调成功==================================="+payerId);
     try {
         Payment payment = executePayment(paymentId,payerId);

         log.info("================================payment===================================");
         log.info(payment.toString());
         log.info("================================payment===================================");
         if (payment.getState().equals("approved")) {
             //修改订单状态

             response.sendRedirect(PAYPAL_SUCCESS_PAGE);
         }else{
             response.sendRedirect(PAYPAL_CANCEL_PAGE);
         }

     } catch (PayPalRESTException e) {
         log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
         log.error(e.getMessage());
         log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

 /**
  * paypal 回调 取消支付
  * @param response
  * @throws IOException
  */
 @GetMapping("/callback/cancel")
 public void cancelPay(HttpServletResponse response) throws IOException {
     log.info("================================payPal 取消支付===================================");
     log.info("================================payPal 取消支付===================================");
     response.sendRedirect(PAYPAL_CANCEL_PAGE);
 }


 @RequestMapping("/success")
 public String success(){
     return "success";
 }

 @RequestMapping("/cancel")
 public String cancel(){
     return "cancel";
 }

 /**
  *
  * @param total
  * @param currency
  * @param method
  * @param intent
  * @param description
  * @param cancelUrl
  * @param successUrl
  * @return
  * @throws PayPalRESTException
  */
 public Payment createPayment(BigDecimal total, String currency, PaypalPaymentMethod method, PaypalPaymentIntent intent,
                              String description, String cancelUrl, String successUrl) throws PayPalRESTException {
     Amount amount = new Amount();
     amount.setCurrency(currency);
     amount.setTotal(String.format("%.2f", total));

     Transaction transaction = new Transaction();
     transaction.setDescription(description);
     transaction.setAmount(amount);

     List<Transaction> transactions = new ArrayList<>();
     transactions.add(transaction);

     Payer payer = new Payer();
     payer.setPaymentMethod(method.toString());

     Payment payment = new Payment();
     payment.setIntent(intent.toString());
     payment.setPayer(payer);
     payment.setTransactions(transactions);
     RedirectUrls redirectUrls = new RedirectUrls();
     redirectUrls.setCancelUrl(cancelUrl);
     redirectUrls.setReturnUrl(successUrl);
     payment.setRedirectUrls(redirectUrls);

     return payment.create(apiContext);
 }

 /**
  *
  * @param paymentId
  * @param payerId
  * @return
  * @throws PayPalRESTException
  */
 public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
     Payment payment = new Payment();
     payment.setId(paymentId);
     PaymentExecution paymentExecute = new PaymentExecution();
     paymentExecute.setPayerId(payerId);
     return payment.execute(apiContext, paymentExecute);
 }

}
